package com.ifp.core.connector;

import java.util.HashMap;
import java.util.Map;

import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.ifp.core.exception.BaseException;
import com.ifp.core.log.LogHandle;
import com.ifp.core.log.Trace;
import com.ifp.core.util.SpringContextsUtil;
import com.ifp.gateway.formatter.IFormatter;
import com.ifp.opengate.boot.constants.Constants;
import com.ifp.opengate.boot.emum.ErrorEnum;
import com.ifp.opengate.boot.utils.IfpRpcServiceUtil;
import com.ifp.opengate.boot.utils.RedisUtils;

/**
 * @className: RPCIFP2ServiceConnector
 * @description: IFPRPC连接器
 * @author: 码农7号
 * @email: guanhh1@belink.com
 * @create: 2019-07-10 09:27
 * @modify zzh 实现IFP2.0dubbo
 **/
public class RPCIFP2ServiceConnector extends AbstractRPCConnector<Map<String, Object>> {

    @Autowired
    IfpRpcServiceUtil ifpRpcServiceUtil;

    @Autowired
    private LogHandle logHandle;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * Redis 缓存中，Dubbo 标签 TAG 的 Key
     */
    public static final String DUBBO_TAG_REDIS_KEY = "opengate_ifp_dubbo_rpc_tag";

    @Override
    public String sendAndReceive(String actionName, String consumerId, Map<String, Object> o) throws Exception {
        Object tagObj = redisUtils.get(DUBBO_TAG_REDIS_KEY);
        Trace.logInfo(Trace.MODULE_COMMON, "opengate_ifp_dubbo_rpc_tag {} ", tagObj);
        if (tagObj != null) {
            RpcContext.getContext().setAttachment("dubbo.tag", String.valueOf(tagObj));
        }
        // else {
        // RpcContext.getContext().removeAttachment("dubbo.tag");
        // }
        Object tempMap = o.get("tempMap");
        Object version = getVersion();
        if (tempMap instanceof Map) {
            version = ((Map)tempMap).get(Constants.SUBCRIBE_VERSION);
            Trace.logInfo(Trace.MODULE_COMMON, "opengate_ifp_dubbo_rpc_version {} ", version);
        }
        String beanKey = consumerId + version + Constants.SUBSCRIBER;
        if (SpringContextsUtil.containsBean(beanKey) && !getRpcConsumerStateMap().isEmpty()
            && getRpcConsumerStateMap().get(beanKey) != null && getRpcConsumerStateMap().get(beanKey)) {
            GenericService flowService = (GenericService)SpringContextsUtil.getRemoteBean(beanKey);

            return getRecMsg(o, flowService);
        } else {
            GenericService flowService =
                ifpRpcServiceUtil.deployDubboRpcCustomer(actionName, consumerId, String.valueOf(version), o);
            if (null != flowService) {
                getRpcConsumerStateMap().put(beanKey, true);
                return getRecMsg(o, flowService);
            }
            throw new BaseException(ErrorEnum.connectError.code(), ErrorEnum.connectError.msg());
        }
    }

    /**
     * 获取报文返回参数
     *
     * @param o
     * @param genericService
     * @return
     * @throws Exception
     */
    private String getRecMsg(Map<String, Object> o, GenericService genericService) throws Exception {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            Map<String, Object> sendContextMap = new HashMap(0);
            this.logHandle.getFlumeLogInfToMap(sendContextMap);
            String cid = this.logHandle.getCallId();
            if (this.logHandle.isPrintRPCSvcInfo()) {
                sendContextMap.put("pcid", cid);
            }
            sendContextMap.put("reqId", o.get("reqId"));
            // 暂时屏蔽存放无用参数信息 by liulx
            // sendContextMap.put("dataMap", o.get("requestMap"));
            Trace.log(Trace.MODULE_TRACE, Trace.LEVEL_INFO,
                "==========================Tread.id========================:{}",
                Thread.currentThread().getName() + "-" + Thread.currentThread().getId());
            Map<String, Object> objectMap = (Map<String, Object>)genericService.$invoke("execute",
                new String[] {"java.util.Map"}, new Object[] {o});
            Map<String, Object> header = (Map<String, Object>)o.get("header");
            header.put("errorCode", "0");
            header.put("errorMsg", "成功");
            resultMap.put("header", header);
            resultMap.put("body", objectMap);
        } catch (Exception e) {
            Trace.log(Trace.MODULE_TRACE, Trace.LEVEL_ERROR, "get recMap is error:{}", e);
            throw new BaseException(ErrorEnum.connectError.code(), ErrorEnum.connectError.msg());
        }
        return JSON.toJSONString(resultMap);
    }

    /**
     * 初始化协议版本及连接协议ip
     */
    @Override
    public void initConnector() {
        this.registry = ifpRpcServiceUtil.deployRegistry(getBeanId(), getBeanName(),
            "zookeeper://" + getIp() + ":" + getPort(), getUsname(), getPasswd());
    }

    @Override
    public String getIp() {
        return super.getIp();
    }

    @Override
    public void setIp(String ip) {
        super.setIp(ip);
    }

    @Override
    public String getPort() {
        return super.getPort();
    }

    @Override
    public void setPort(String port) {
        super.setPort(port);
    }

    @Override
    public String getUsname() {
        return super.getUsname();
    }

    @Override
    public void setUsname(String usname) {
        super.setUsname(usname);
    }

    @Override
    public String getPasswd() {
        return super.getPasswd();
    }

    @Override
    public void setPasswd(String passwd) {
        super.setPasswd(passwd);
    }

    @Override
    public IFormatter getRequestFormatter() {
        return super.getRequestFormatter();
    }

    @Override
    public void setRequestFormatter(IFormatter requestFormatter) {
        super.setRequestFormatter(requestFormatter);
    }

    @Override
    public IFormatter getResponseFormatter() {
        return super.getResponseFormatter();
    }

    @Override
    public void setResponseFormatter(IFormatter responseFormatter) {
        super.setResponseFormatter(responseFormatter);
    }

    RegistryConfig registry;

}
